{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Project 8: Backtesting\n",
    "\n",
    "In this project, you will build a fairly realistic backtester that uses the Barra data. The backtester will perform portfolio optimization that includes transaction costs, and you'll implement it with computational efficiency in mind, to allow for a reasonably fast backtest. You'll also use performance attribution to identify the major drivers of your portfolio's profit-and-loss (PnL). You will have the option to modify and customize the backtest as well.\n",
    "\n",
    "\n",
    "## Instructions\n",
    "\n",
    "Each problem consists of a function to implement and instructions on how to implement the function.  The parts of the function that need to be implemented are marked with a `# TODO` comment. Your code will be checked for the correct solution when you submit it to Udacity.\n",
    "\n",
    "\n",
    "## Packages\n",
    "\n",
    "When you implement the functions, you'll only need to you use the packages you've used in the classroom, like [Pandas](https://pandas.pydata.org/) and [Numpy](http://www.numpy.org/). These packages will be imported for you. We recommend you don't add any import statements, otherwise the grader might not be able to run your code.\n",
    "\n",
    "### Install Packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: matplotlib==2.1.0 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (2.1.0)\n",
      "Collecting numpy==1.16.1 (from -r requirements.txt (line 2))\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/f5/bf/4981bcbee43934f0adb8f764a1e70ab0ee5a448f6505bd04a87a2fda2a8b/numpy-1.16.1-cp36-cp36m-manylinux1_x86_64.whl (17.3MB)\n",
      "\u001b[K    100% |████████████████████████████████| 17.3MB 1.9MB/s eta 0:00:01   20% |██████▌                         | 3.5MB 31.7MB/s eta 0:00:01\n",
      "\u001b[?25hCollecting pandas==0.24.1 (from -r requirements.txt (line 3))\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/e6/de/a0d3defd8f338eaf53ef716e40ef6d6c277c35d50e09b586e170169cdf0d/pandas-0.24.1-cp36-cp36m-manylinux1_x86_64.whl (10.1MB)\n",
      "\u001b[K    100% |████████████████████████████████| 10.1MB 4.9MB/s eta 0:00:01   38% |████████████▎                   | 3.9MB 27.9MB/s eta 0:00:01    66% |█████████████████████▏          | 6.7MB 29.3MB/s eta 0:00:01    78% |█████████████████████████       | 7.9MB 30.5MB/s eta 0:00:01\n",
      "\u001b[?25hCollecting patsy==0.5.1 (from -r requirements.txt (line 4))\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/ea/0c/5f61f1a3d4385d6bf83b83ea495068857ff8dfb89e74824c6e9eb63286d8/patsy-0.5.1-py2.py3-none-any.whl (231kB)\n",
      "\u001b[K    100% |████████████████████████████████| 235kB 20.0MB/s ta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: scipy==0.19.1 in /opt/conda/lib/python3.6/site-packages (from -r requirements.txt (line 5)) (0.19.1)\n",
      "Collecting statsmodels==0.9.0 (from -r requirements.txt (line 6))\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/85/d1/69ee7e757f657e7f527cbf500ec2d295396e5bcec873cf4eb68962c41024/statsmodels-0.9.0-cp36-cp36m-manylinux1_x86_64.whl (7.4MB)\n",
      "\u001b[K    100% |████████████████████████████████| 7.4MB 5.7MB/s eta 0:00:01    23% |███████▌                        | 1.7MB 26.7MB/s eta 0:00:01\n",
      "\u001b[?25hCollecting tqdm==4.19.5 (from -r requirements.txt (line 7))\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/71/3c/341b4fa23cb3abc335207dba057c790f3bb329f6757e1fcd5d347bcf8308/tqdm-4.19.5-py2.py3-none-any.whl (51kB)\n",
      "\u001b[K    100% |████████████████████████████████| 61kB 12.7MB/s ta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: six>=1.10 in /opt/conda/lib/python3.6/site-packages (from matplotlib==2.1.0->-r requirements.txt (line 1)) (1.11.0)\n",
      "Requirement already satisfied: python-dateutil>=2.0 in /opt/conda/lib/python3.6/site-packages (from matplotlib==2.1.0->-r requirements.txt (line 1)) (2.6.1)\n",
      "Requirement already satisfied: pytz in /opt/conda/lib/python3.6/site-packages (from matplotlib==2.1.0->-r requirements.txt (line 1)) (2017.3)\n",
      "Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.6/site-packages/cycler-0.10.0-py3.6.egg (from matplotlib==2.1.0->-r requirements.txt (line 1)) (0.10.0)\n",
      "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /opt/conda/lib/python3.6/site-packages (from matplotlib==2.1.0->-r requirements.txt (line 1)) (2.2.0)\n",
      "\u001b[31mtensorflow 1.3.0 requires tensorflow-tensorboard<0.2.0,>=0.1.0, which is not installed.\u001b[0m\n",
      "\u001b[31mmoviepy 0.2.3.2 has requirement tqdm==4.11.2, but you'll have tqdm 4.19.5 which is incompatible.\u001b[0m\n",
      "Installing collected packages: numpy, pandas, patsy, statsmodels, tqdm\n",
      "  Found existing installation: numpy 1.12.1\n",
      "    Uninstalling numpy-1.12.1:\n",
      "      Successfully uninstalled numpy-1.12.1\n",
      "  Found existing installation: pandas 0.23.3\n",
      "    Uninstalling pandas-0.23.3:\n",
      "      Successfully uninstalled pandas-0.23.3\n",
      "  Found existing installation: patsy 0.4.1\n",
      "    Uninstalling patsy-0.4.1:\n",
      "      Successfully uninstalled patsy-0.4.1\n",
      "  Found existing installation: statsmodels 0.8.0\n",
      "    Uninstalling statsmodels-0.8.0:\n",
      "      Successfully uninstalled statsmodels-0.8.0\n",
      "  Found existing installation: tqdm 4.11.2\n",
      "    Uninstalling tqdm-4.11.2:\n",
      "      Successfully uninstalled tqdm-4.11.2\n",
      "Successfully installed numpy-1.16.1 pandas-0.24.1 patsy-0.5.1 statsmodels-0.9.0 tqdm-4.19.5\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "!{sys.executable} -m pip install -r requirements.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load Packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy\n",
    "import patsy\n",
    "import pickle\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "import scipy.sparse\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from statistics import median\n",
    "from scipy.stats import gaussian_kde\n",
    "from statsmodels.formula.api import ols\n",
    "from tqdm import tqdm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Data\n",
    "\n",
    "We’ll be using the Barra dataset to get factors that can be used to predict risk. Loading and parsing the raw Barra data can be a very slow process that can significantly slow down your backtesting. For this reason, it's important to pre-process the data beforehand. For your convenience, the Barra data has already been pre-processed for you and saved into pickle files. You will load the Barra data from these pickle files.\n",
    "\n",
    "In the code below, we start by loading `2004` factor data from the `pandas-frames.2004.pickle` file. We also load the `2003` and `2004` covariance data from the `covaraince.2003.pickle`  and `covaraince.2004.pickle` files. You are encouraged  to customize the data range for your backtest. For example, we recommend starting with two or three years of factor data. Remember that the covariance data should include all the years that you choose for the factor data,   and also one year earlier. For example, in the code below we are using  `2004` factor data, therefore, we must include `2004` in our covariance data, but also the previous year, `2003`. If you don't remember why must include this previous year, feel free to review the lessons."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "barra_dir = '../../data/project_8_barra/'\n",
    "\n",
    "data = {}\n",
    "for year in [2004]:\n",
    "    fil = barra_dir + \"pandas-frames.\" + str(year) + \".pickle\"\n",
    "    data.update(pickle.load( open( fil, \"rb\" ) ))\n",
    "    \n",
    "covariance = {}\n",
    "for year in [2004]:\n",
    "    fil = barra_dir + \"covariance.\" + str(year) + \".pickle\"\n",
    "    covariance.update(pickle.load( open(fil, \"rb\" ) ))\n",
    "    \n",
    "daily_return = {}\n",
    "for year in [2004, 2005]:\n",
    "    fil = barra_dir + \"price.\" + str(year) + \".pickle\"\n",
    "    daily_return.update(pickle.load( open(fil, \"rb\" ) ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Shift Daily Returns Data (TODO)\n",
    "\n",
    "In the cell below, we want to incorporate a realistic time delay that exists in live trading, we’ll use a two day delay for the `daily_return` data. That means the `daily_return` should be two days after the data in `data` and `cov_data`. Combine `daily_return` and `data` together in a dict called `frames`.\n",
    "\n",
    "Since reporting of PnL is usually for the date of the returns, make sure to use the two day delay dates (dates that match the `daily_return`) when building `frames`. This means calling `frames['20040108']` will get you the prices from \"20040108\" and the data from `data` at \"20040106\".\n",
    "\n",
    "Note: We're not shifting `covariance`, since we'll use the \"DataDate\" field in `frames` to lookup the covariance data. The \"DataDate\" field contains the date when the `data` in `frames` was recorded. For example, `frames['20040108']` will give you a value of \"20040106\" for the field \"DataDate\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "frames ={}\n",
    "dlyreturn_n_days_delay = 2\n",
    "\n",
    "# TODO: Implement\n",
    "shift = zip( sorted(data.keys()), sorted(daily_return.keys())[dlyreturn_n_days_delay : len(data)+dlyreturn_n_days_delay ] )\n",
    "\n",
    "for i, j in shift:\n",
    "#     print(i)\n",
    "#     print(j)\n",
    "    frames[j] = data[i].merge(daily_return[j], on=\"Barrid\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add Daily Returns date column (Optional)\n",
    "Name the column `DlyReturnDate`.\n",
    "**Hint**: create a list containing copies of the date, then create a pandas series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Winsorize\n",
    "\n",
    "As we have done in other projects, we'll want to avoid extremely positive or negative values in our data. Will therefore create a function, `wins`, that will clip our values to a minimum and maximum range. This process is called **Winsorizing**. Remember that this helps us handle noise, which may otherwise cause unusually large positions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def wins(x,a,b):\n",
    "    return np.where(x <= a,a, np.where(x >= b, b, x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Density Plot\n",
    "\n",
    "Let's check our `wins` function by taking a look at the distribution of returns for a single day `20040102`. We will clip our data from `-0.1` to `0.1` and plot it using our `density_plot` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f8041e78ac8>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def density_plot(data): \n",
    "    density = gaussian_kde(data)\n",
    "    xs = np.linspace(np.min(data),np.max(data),200)\n",
    "    density.covariance_factor = lambda : .25\n",
    "    density._compute_covariance()\n",
    "    plt.plot(xs,density(xs))\n",
    "    plt.xlabel('Daily Returns')\n",
    "    plt.ylabel('Density')\n",
    "    plt.show()\n",
    "    \n",
    "test = frames['20040108']\n",
    "test['DlyReturn'] = wins(test['DlyReturn'],-0.1,0.1)\n",
    "density_plot(test['DlyReturn'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Factor Exposures and Factor Returns\n",
    "\n",
    "Recall that:\n",
    "\n",
    "$r_{i,t} = \\sum_{j=1}^{k} (\\beta_{i,j,t-2} \\times f_{j,t})$  \n",
    "where $i=1...N$ (N assets),   \n",
    "and $j=1...k$ (k factors).\n",
    "\n",
    "where $r_{i,t}$ is the return, $\\beta_{i,j,t-2}$ is the factor exposure, and $f_{j,t}$ is the factor return. Since we get the factor exposures from the Barra data, and we know the returns, it is possible to estimate the factor returns. In this notebook, we will use the Ordinary Least Squares (OLS) method to estimate the factor exposures, $f_{j,t}$, by using $\\beta_{i,j,t-2}$ as the independent variable, and $r_{i,t}$ as the dependent variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_formula(factors, Y):\n",
    "    L = [\"0\"]\n",
    "    L.extend(factors)\n",
    "    return Y + \" ~ \" + \" + \".join(L)\n",
    "\n",
    "def factors_from_names(n):\n",
    "    return list(filter(lambda x: \"USFASTD_\" in x, n))\n",
    "\n",
    "def estimate_factor_returns(df): \n",
    "    ## build universe based on filters \n",
    "    estu = df.loc[df.IssuerMarketCap > 1e9].copy(deep=True)\n",
    "  \n",
    "    ## winsorize returns for fitting \n",
    "    estu['DlyReturn'] = wins(estu['DlyReturn'], -0.25, 0.25)\n",
    "  \n",
    "    all_factors = factors_from_names(list(df))\n",
    "    form = get_formula(all_factors, \"DlyReturn\")\n",
    "    model = ols(form, data=estu)\n",
    "    results = model.fit()\n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "facret = {}\n",
    "\n",
    "for date in frames:\n",
    "    facret[date] = estimate_factor_returns(frames[date]).params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_dates = sorted(list(map(lambda date: pd.to_datetime(date, format='%Y%m%d'), frames.keys())))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Choose Alpha Factors\n",
    "\n",
    "We will now choose our alpha factors. Barra's factors include some alpha factors that we have seen before, such as:\n",
    "\n",
    "* **USFASTD_1DREVRSL** : Reversal\n",
    "\n",
    "* **USFASTD_EARNYILD** : Earnings Yield\n",
    "\n",
    "* **USFASTD_VALUE** : Value\n",
    "\n",
    "* **USFASTD_SENTMT** : Sentiment\n",
    "\n",
    "We will choose these alpha factors for now, but you are encouraged to come back to this later and try other factors as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.6/site-packages/pandas/plotting/_converter.py:129: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.\n",
      "\n",
      "To register the converters:\n",
      "\t>>> from pandas.plotting import register_matplotlib_converters\n",
      "\t>>> register_matplotlib_converters()\n",
      "  warnings.warn(msg, FutureWarning)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f804552fda0>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "alpha_factors = [\"USFASTD_1DREVRSL\", \"USFASTD_EARNYILD\", \"USFASTD_VALUE\", \"USFASTD_SENTMT\"]\n",
    "\n",
    "facret_df = pd.DataFrame(index = my_dates)\n",
    "\n",
    "for dt in my_dates: \n",
    "    for alp in alpha_factors: \n",
    "        facret_df.at[dt, alp] = facret[dt.strftime('%Y%m%d')][alp]\n",
    "\n",
    "for column in facret_df.columns:\n",
    "        plt.plot(facret_df[column].cumsum(), label=column)\n",
    "plt.legend(loc='upper left')\n",
    "plt.xlabel('Date')\n",
    "plt.ylabel('Cumulative Factor Returns')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Merge Previous Portfolio Holdings \n",
    "\n",
    "In order to optimize our portfolio we will use the previous day's holdings to estimate the trade size and transaction costs. In order to keep track of the holdings from the previous day we will include a column to hold the portfolio holdings of the previous day. These holdings of all our assets will be initialized to zero when the backtest first starts."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def clean_nas(df): \n",
    "    numeric_columns = df.select_dtypes(include=[np.number]).columns.tolist()\n",
    "    \n",
    "    for numeric_column in numeric_columns: \n",
    "        df[numeric_column] = np.nan_to_num(df[numeric_column])\n",
    "    \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "previous_holdings = pd.DataFrame(data = {\"Barrid\" : [\"USA02P1\"], \"h.opt.previous\" : np.array(0)})\n",
    "df = frames[my_dates[0].strftime('%Y%m%d')]\n",
    "\n",
    "df = df.merge(previous_holdings, how = 'left', on = 'Barrid')\n",
    "df = clean_nas(df)\n",
    "df.loc[df['SpecRisk'] == 0]['SpecRisk'] = median(df['SpecRisk'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build Universe Based on Filters (TODO)\n",
    "\n",
    "In the cell below, implement the function `get_universe` that creates a stock universe by selecting only those companies that have a market capitalization of at least 1 billion dollars **OR** that are in the previous day's holdings, even if on the current day, the company no longer meets the 1 billion dollar criteria.\n",
    "\n",
    "When creating the universe, make sure you use the `.copy()` attribute to create a copy of the data. Also, it is very important to make sure that we are not looking at returns when forming the portfolio! to make this impossible, make sure to drop the column containing the daily return."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_universe(df):\n",
    "    \"\"\"\n",
    "    Create a stock universe based on filters\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    df : DataFrame\n",
    "        All stocks\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    universe : DataFrame\n",
    "        Selected stocks based on filters\n",
    "    \"\"\"\n",
    "    \n",
    "#     print(df)\n",
    "    x = df.copy().drop('DlyReturn', axis=1)\n",
    "    universe =x[ (x['IssuerMarketCap'] >= 1e9) | (np.abs(x['h.opt.previous']) > 0) ]\n",
    "#     print(uni)\n",
    "    return universe\n",
    "    \n",
    "\n",
    "universe = get_universe(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "date = str(int(universe['DataDate'][1])) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Factors\n",
    "\n",
    "We will now extract both the risk factors and alpha factors. We begin by first getting all the factors using the `factors_from_names` function defined previously."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_factors = factors_from_names(list(universe))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will now create the function `setdiff` to just select the factors that we have not defined as alpha factors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "def setdiff(temp1, temp2): \n",
    "    s = set(temp2)\n",
    "    temp3 = [x for x in temp1 if x not in s]\n",
    "    return temp3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "risk_factors = setdiff(all_factors, alpha_factors)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also save the column that contains the previous holdings in a separate variable because we are going to use it later when we perform our portfolio optimization."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "h0 = universe['h.opt.previous']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Matrix of Risk Factor Exposures\n",
    "\n",
    "Our dataframe contains several columns that we'll use as risk factors exposures.  Extract these and put them into a matrix.\n",
    "\n",
    "The data, such as industry category, are already one-hot encoded, but if this were not the case, then using `patsy.dmatrices` would help, as this function extracts categories and performs the one-hot encoding.  We'll practice using this package, as you may find it useful with future data sets.  You could also store the factors in a dataframe if you prefer.\n",
    "\n",
    "#### How to use patsy.dmatrices\n",
    "\n",
    "`patsy.dmatrices` takes in a formula and the dataframe.  The formula tells the function which columns to take.  The formula will look something like this:  \n",
    "`SpecRisk ~ 0 + USFASTD_AERODEF + USFASTD_AIRLINES + ...`  \n",
    "where the variable to the left of the ~ is the \"dependent variable\" and the others to the right are the independent variables (as if we were preparing data to be fit to a model).\n",
    "\n",
    "This just means that the `pasty.dmatrices` function will return two matrix variables, one that contains the single column for the dependent variable `outcome`, and the independent variable columns are stored in a matrix `predictors`.\n",
    "\n",
    "The `predictors` matrix will contain the matrix of risk factors, which is what we want.  We don't actually need the `outcome` matrix; it's just created because that's the way patsy.dmatrices works."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "formula = get_formula(risk_factors, \"SpecRisk\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "def model_matrix(formula, data): \n",
    "    outcome, predictors = patsy.dmatrices(formula, data)\n",
    "    return predictors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "B = model_matrix(formula, universe)\n",
    "BT = B.transpose()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calculate Specific Variance\n",
    "\n",
    "Notice that the specific risk data is in percent:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     9.014505\n",
       "1    11.726327\n",
       "Name: SpecRisk, dtype: float64"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "universe['SpecRisk'][0:2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Therefore, in order to get the specific variance for each stock in the universe we first need to multiply these values by `0.01`  and then square them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "specVar = (0.01 * universe['SpecRisk']) ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Factor covariance matrix (TODO)\n",
    "\n",
    "Note that we already have factor covariances from Barra data, which is stored in the variable `covariance`.  `covariance` is a dictionary, where the key is each day's date, and the value is a dataframe containing the factor covariances."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Factor1</th>\n",
       "      <th>Factor2</th>\n",
       "      <th>VarCovar</th>\n",
       "      <th>DataDate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>1.958869</td>\n",
       "      <td>20040102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>USFASTD_BETA</td>\n",
       "      <td>1.602458</td>\n",
       "      <td>20040102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>USFASTD_DIVYILD</td>\n",
       "      <td>-0.012642</td>\n",
       "      <td>20040102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>USFASTD_DWNRISK</td>\n",
       "      <td>-0.064387</td>\n",
       "      <td>20040102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>USFASTD_1DREVRSL</td>\n",
       "      <td>USFASTD_EARNQLTY</td>\n",
       "      <td>0.046573</td>\n",
       "      <td>20040102</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            Factor1           Factor2  VarCovar  DataDate\n",
       "0  USFASTD_1DREVRSL  USFASTD_1DREVRSL  1.958869  20040102\n",
       "1  USFASTD_1DREVRSL      USFASTD_BETA  1.602458  20040102\n",
       "2  USFASTD_1DREVRSL   USFASTD_DIVYILD -0.012642  20040102\n",
       "3  USFASTD_1DREVRSL   USFASTD_DWNRISK -0.064387  20040102\n",
       "4  USFASTD_1DREVRSL  USFASTD_EARNQLTY  0.046573  20040102"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "covariance['20040102'].head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the code below, implement the function `diagonal_factor_cov` to create the factor covariance matrix. Note that the covariances are given in percentage units squared.  Therefore you must re-scale them appropriately so that they're in decimals squared. Use the given `colnames` function to get the column names from `B`. \n",
    "\n",
    "When creating factor covariance matrix, you can store the factor variances and covariances, or just store the factor variances.  Try both, and see if you notice any differences."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def colnames(B):\n",
    "    if type(B) == patsy.design_info.DesignMatrix: \n",
    "        return B.design_info.column_names\n",
    "    if type(B) == pandas.core.frame.DataFrame: \n",
    "        return B.columns.tolist()\n",
    "    return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "def diagonal_factor_cov(date, B):\n",
    "    \"\"\"\n",
    "    Create the factor covariance matrix\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    date : string\n",
    "           date. For example 20040102\n",
    "        \n",
    "    B : patsy.design_info.DesignMatrix OR pandas.core.frame.DataFrame\n",
    "        Matrix of Risk Factors\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    Fm : Numpy ndarray\n",
    "        factor covariance matrix\n",
    "    \"\"\"\n",
    "    \n",
    "#     print(date)\n",
    "#     print(B)\n",
    "    Fm = np.zeros( [ np.shape(B)[1], np.shape(B)[1] ] )\n",
    "    covar = covariance[date]\n",
    "#     print(Fm)\n",
    "    for x in range(0, np.shape(B)[1]):\n",
    "        c = colnames(B)[x]\n",
    "        Fm[x,x] = covar.loc[ (covar.Factor1 == c) & (covar.Factor2 == c), 'VarCovar' ].iloc[0] * .01**2\n",
    "#     print(Fm)\n",
    "    \n",
    "    return Fm\n",
    "\n",
    "Fvar = diagonal_factor_cov(date, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transaction Costs\n",
    "\n",
    "To get the transaction cost, or slippage, we have to multiply the price change due to market impact by the amount of dollars traded:\n",
    "\n",
    "$$\n",
    "\\mbox{tcost_{i,t}} = \\% \\Delta \\mbox{price}_{i,t} \\times \\mbox{trade}_{i,t}\n",
    "$$\n",
    "\n",
    "In summation notation it looks like this:  \n",
    "$$\n",
    "\\mbox{tcost}_{i,t} = \\sum_i^{N} \\lambda_{i,t} (h_{i,t} - h_{i,t-1})^2\n",
    "$$  \n",
    "where\n",
    "$$\n",
    "\\lambda_{i,t} = \\frac{1}{10\\times \\mbox{ADV}_{i,t}}\n",
    "$$\n",
    "\n",
    "Note that since we're dividing by ADV, we'll want to handle cases when ADV is missing or zero.  In those instances, we can set ADV to a small positive number, such as 10,000, which, in practice assumes that the stock is illiquid. In the code below if there is no volume information we assume the asset is illiquid."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_lambda(universe, composite_volume_column = 'ADTCA_30'):\n",
    "    universe.loc[np.isnan(universe[composite_volume_column]), composite_volume_column] = 1.0e4\n",
    "    universe.loc[universe[composite_volume_column] == 0, composite_volume_column] = 1.0e4 \n",
    "\n",
    "    adv = universe[composite_volume_column]\n",
    "    \n",
    "    return 0.1 / adv\n",
    "\n",
    "Lambda = get_lambda(universe)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Alpha Combination (TODO)\n",
    "\n",
    "In the code below create a matrix of alpha factors and return it from the function `get_B_alpha`. Create this matrix in the same way you created the matrix of risk factors, i.e. using the `get_formula` and `model_matrix` functions we have defined above. Feel free to go back and look at the previous code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_B_alpha(alpha_factors, universe):\n",
    "    \n",
    "#     print(alpha_factors)\n",
    "#     print(universe)\n",
    "    return model_matrix(get_formula(alpha_factors, 'SpecRisk'), universe)\n",
    "\n",
    "B_alpha = get_B_alpha(alpha_factors, universe)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that you have the matrix containing the alpha factors we will combine them by adding its rows. By doing this we will collapse the `B_alpha` matrix into a single alpha vector. We'll multiply by `1e-4` so that the expression of expected portfolio return, $\\alpha^T \\mathbf{h}$, is in dollar units. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_alpha_vec(B_alpha):\n",
    "    \"\"\"\n",
    "    Create an alpha vecrtor\n",
    "\n",
    "    Parameters\n",
    "    ----------        \n",
    "    B_alpha : patsy.design_info.DesignMatrix \n",
    "        Matrix of Alpha Factors\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    alpha_vec : patsy.design_info.DesignMatrix \n",
    "        alpha vecrtor\n",
    "    \"\"\"\n",
    "    \n",
    "    # TODO: Implement\n",
    "#     print(B_alpha)\n",
    "    return B_alpha.sum(axis=1) * 1e-4\n",
    "\n",
    "alpha_vec = get_alpha_vec(B_alpha)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Optional Challenge\n",
    "\n",
    "You can also try to a more sophisticated method of alpha combination, by choosing the holding for each alpha based on the same metric of its performance, such as the factor returns, or sharpe ratio.  To make this more realistic, you can calculate a rolling average of the sharpe ratio, which is updated for each day.  Remember to only use data that occurs prior to the date of each optimization, and not data that occurs in the future.  Also, since factor returns and sharpe ratios may be negative, consider using a `max` function to give the holdings a lower bound of zero."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Objective function (TODO)\n",
    "\n",
    "The objective function is given by:\n",
    "\n",
    "$$\n",
    "f(\\mathbf{h}) = \\frac{1}{2}\\kappa \\mathbf{h}_t^T\\mathbf{Q}^T\\mathbf{Q}\\mathbf{h}_t + \\frac{1}{2} \\kappa \\mathbf{h}_t^T \\mathbf{S} \\mathbf{h}_t - \\mathbf{\\alpha}^T \\mathbf{h}_t + (\\mathbf{h}_{t} - \\mathbf{h}_{t-1})^T \\mathbf{\\Lambda} (\\mathbf{h}_{t} - \\mathbf{h}_{t-1})\n",
    "$$\n",
    "\n",
    "Where the terms correspond to: factor risk + idiosyncratic risk - expected portfolio return + transaction costs, respectively. We should also note that $\\textbf{Q}^T\\textbf{Q}$ is defined to be the same as $\\textbf{BFB}^T$.  Review the lessons if you need a refresher of how we get $\\textbf{Q}$.\n",
    "\n",
    "Our objective is to minimize this objective function. To do this, we will use Scipy's optimization function:\n",
    "\n",
    "`scipy.optimize.fmin_l_bfgs_b(func, initial_guess, func_gradient)`\n",
    "\n",
    "where:\n",
    "\n",
    "* **func** : is the function we want to minimize\n",
    "\n",
    "* **initial_guess** : is out initial guess\n",
    "\n",
    "* **func_gradient** : is the gradient of the function we want to minimize\n",
    "\n",
    "So, in order to use the `scipy.optimize.fmin_l_bfgs_b` function we first need to define its parameters.\n",
    "\n",
    "In the code below implement the function `obj_func(h)` that corresponds to the objective function above that we want to minimize. We will set the risk aversion to be `1.0e-6`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "risk_aversion = 1.0e-6\n",
    "\n",
    "def get_obj_func(h0, risk_aversion, Q, specVar, alpha_vec, Lambda): \n",
    "    def obj_func(h):\n",
    "        a = ( risk_aversion * np.sum(np.matmul(Q, h)**2) + risk_aversion * np.dot(h**2, specVar) ) * .5 + np.dot( (h-h0)**2, Lambda ) - np.dot(h, alpha_vec)\n",
    "\n",
    "\n",
    "        return a\n",
    "    \n",
    "    return obj_func"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Gradient (TODO)\n",
    "\n",
    "Now that we can generate the objective function using `get_obj_func`, we can now create a similar function with its gradient. The reason we're interested in calculating the gradient is so that we can tell the optimizer in which direction, and how much, it should shift the portfolio holdings in order to improve the objective function (minimize variance, minimize transaction cost, and maximize expected portfolio return).\n",
    "\n",
    "Before we implement the function we first need to know what the gradient looks like. The gradient, or derivative of the objective function, with respect to the portfolio holdings h, is given by:  \n",
    "\n",
    "$$\n",
    "f'(\\mathbf{h}) = \\frac{1}{2}\\kappa (2\\mathbf{Q}^T\\mathbf{Qh}) + \\frac{1}{2}\\kappa (2\\mathbf{Sh}) - \\mathbf{\\alpha} + 2(\\mathbf{h}_{t} - \\mathbf{h}_{t-1}) \\mathbf{\\Lambda}\n",
    "$$\n",
    "\n",
    "In the code below, implement the function `grad(h)` that corresponds to the function of the gradient given above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_grad_func(h0, risk_aversion, Q, QT, specVar, alpha_vec, Lambda):\n",
    "    def grad_func(h):\n",
    "        x = Lambda * 2*(h-h0) + ( h*specVar + np.matmul(QT, np.matmul(Q,h)) ) *risk_aversion - alpha_vec \n",
    "        y  = np.asarray(x)\n",
    "        return y\n",
    "    \n",
    "    return grad_func"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Optimize (TODO)\n",
    "\n",
    "Now that we can generate the objective function using `get_obj_func`, and its corresponding gradient using `get_grad_func` we are ready to minimize the objective function using Scipy's optimization function. For this, we will use out initial holdings as our `initial_guess` parameter.\n",
    "\n",
    "In the cell below, implement the function `get_h_star` that optimizes the objective function. Use the objective function (`obj_func`) and gradient function (`grad_func`) provided within `get_h_star` to optimize the objective function using the `scipy.optimize.fmin_l_bfgs_b` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "risk_aversion = 1.0e-6\n",
    "\n",
    "Q = np.matmul(scipy.linalg.sqrtm(Fvar), BT)\n",
    "QT = Q.transpose()\n",
    "\n",
    "def get_h_star(risk_aversion, Q, QT, specVar, alpha_vec, h0, Lambda):\n",
    "    \"\"\"\n",
    "    Optimize the objective function\n",
    "\n",
    "    Parameters\n",
    "    ----------        \n",
    "    risk_aversion : int or float \n",
    "        Trader's risk aversion\n",
    "        \n",
    "    Q : patsy.design_info.DesignMatrix \n",
    "        Q Matrix\n",
    "        \n",
    "    QT : patsy.design_info.DesignMatrix \n",
    "        Transpose of the Q Matrix\n",
    "        \n",
    "    specVar: Pandas Series \n",
    "        Specific Variance\n",
    "        \n",
    "    alpha_vec: patsy.design_info.DesignMatrix \n",
    "        alpha vector\n",
    "        \n",
    "    h0 : Pandas Series  \n",
    "        initial holdings\n",
    "        \n",
    "    Lambda : Pandas Series  \n",
    "        Lambda\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    optimizer_result[0]: Numpy ndarray \n",
    "        optimized holdings\n",
    "    \"\"\"\n",
    "    obj_func = get_obj_func(h0, risk_aversion, Q, specVar, alpha_vec, Lambda)\n",
    "    grad_func = get_grad_func(h0, risk_aversion, Q, QT, specVar, alpha_vec, Lambda)\n",
    "    \n",
    "    \n",
    "    \n",
    "    return scipy.optimize.fmin_l_bfgs_b(obj_func, h0, fprime=grad_func)[0]\n",
    "\n",
    "h_star = get_h_star(risk_aversion, Q, QT, specVar, alpha_vec, h0, Lambda)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After we have optimized our objective function we can now use, `h_star` to create our optimal portfolio:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_portfolio = pd.DataFrame(data = {\"Barrid\" : universe['Barrid'], \"h.opt\" : h_star})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Risk Exposures (TODO)\n",
    "\n",
    "We can also use `h_star` to calculate our portfolio's risk and alpha exposures.\n",
    "\n",
    "In the cells below implement the functions `get_risk_exposures` and `get_portfolio_alpha_exposure` that calculate the portfolio's risk and alpha exposures, respectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_risk_exposures(B, BT, h_star):\n",
    "    \"\"\"\n",
    "    Calculate portfolio's Risk Exposure\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    B : patsy.design_info.DesignMatrix \n",
    "        Matrix of Risk Factors\n",
    "        \n",
    "    BT : patsy.design_info.DesignMatrix \n",
    "        Transpose of Matrix of Risk Factors\n",
    "        \n",
    "    h_star: Numpy ndarray \n",
    "        optimized holdings\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    risk_exposures : Pandas Series\n",
    "        Risk Exposures\n",
    "    \"\"\"\n",
    "    \n",
    "\n",
    "    \n",
    "    return pd.Series( np.matmul(BT, h_star), index =colnames(B) )\n",
    "\n",
    "risk_exposures = get_risk_exposures(B, BT, h_star)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_portfolio_alpha_exposure(B_alpha, h_star):\n",
    "    \"\"\"\n",
    "    Calculate portfolio's Alpha Exposure\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    B_alpha : patsy.design_info.DesignMatrix \n",
    "        Matrix of Alpha Factors\n",
    "        \n",
    "    h_star: Numpy ndarray \n",
    "        optimized holdings\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    alpha_exposures : Pandas Series\n",
    "        Alpha Exposures\n",
    "    \"\"\"\n",
    "    \n",
    "    # TODO: Implement\n",
    "    x = np.matmul(B_alpha.transpose(), h_star)\n",
    "    y = pd.Series(x, index = colnames(B_alpha))\n",
    "#     print(y)\n",
    "    return y\n",
    "\n",
    "portfolio_alpha_exposure = get_portfolio_alpha_exposure(B_alpha, h_star)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transaction Costs (TODO)\n",
    "\n",
    "We can also use `h_star` to calculate our total transaction costs:\n",
    "$$\n",
    "\\mbox{tcost} = \\sum_i^{N} \\lambda_{i} (h_{i,t} - h_{i,t-1})^2\n",
    "$$\n",
    "\n",
    "In the cell below, implement the function `get_total_transaction_costs` that calculates the total transaction costs according to the equation above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_total_transaction_costs(h0, h_star, Lambda):\n",
    "    \"\"\"\n",
    "    Calculate Total Transaction Costs\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    h0 : Pandas Series\n",
    "        initial holdings (before optimization)\n",
    "        \n",
    "    h_star: Numpy ndarray \n",
    "        optimized holdings\n",
    "        \n",
    "    Lambda : Pandas Series  \n",
    "        Lambda\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    total_transaction_costs : float\n",
    "        Total Transaction Costs\n",
    "    \"\"\"\n",
    "    \n",
    "    x = np.dot((h_star-h0)**2, Lambda)\n",
    "#     print(x)\n",
    "    \n",
    "    return x\n",
    "\n",
    "total_transaction_costs = get_total_transaction_costs(h0, h_star, Lambda)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Putting It All Together\n",
    "\n",
    "We can now take all the above functions we created above and use them to create a single function, `form_optimal_portfolio` that returns the optimal portfolio, the risk and alpha exposures, and the total transactions costs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "def form_optimal_portfolio(df, previous, risk_aversion):\n",
    "    df = df.merge(previous, how = 'left', on = 'Barrid')\n",
    "    df = clean_nas(df)\n",
    "    df.loc[df['SpecRisk'] == 0]['SpecRisk'] = median(df['SpecRisk'])\n",
    "  \n",
    "    universe = get_universe(df)\n",
    "    date = str(int(universe['DataDate'][1]))\n",
    "  \n",
    "    all_factors = factors_from_names(list(universe))\n",
    "    risk_factors = setdiff(all_factors, alpha_factors)\n",
    "  \n",
    "    h0 = universe['h.opt.previous']\n",
    "  \n",
    "    B = model_matrix(get_formula(risk_factors, \"SpecRisk\"), universe)\n",
    "    BT = B.transpose()\n",
    "  \n",
    "    specVar = (0.01 * universe['SpecRisk']) ** 2\n",
    "    Fvar = diagonal_factor_cov(date, B)\n",
    "    \n",
    "    Lambda = get_lambda(universe)\n",
    "    B_alpha = get_B_alpha(alpha_factors, universe)\n",
    "    alpha_vec = get_alpha_vec(B_alpha)\n",
    "  \n",
    "    Q = np.matmul(scipy.linalg.sqrtm(Fvar), BT)\n",
    "    QT = Q.transpose()\n",
    "    \n",
    "    h_star = get_h_star(risk_aversion, Q, QT, specVar, alpha_vec, h0, Lambda)\n",
    "    opt_portfolio = pd.DataFrame(data = {\"Barrid\" : universe['Barrid'], \"h.opt\" : h_star})\n",
    "    \n",
    "    risk_exposures = get_risk_exposures(B, BT, h_star)\n",
    "    portfolio_alpha_exposure = get_portfolio_alpha_exposure(B_alpha, h_star)\n",
    "    total_transaction_costs = get_total_transaction_costs(h0, h_star, Lambda)\n",
    "  \n",
    "    return {\n",
    "        \"opt.portfolio\" : opt_portfolio, \n",
    "        \"risk.exposures\" : risk_exposures, \n",
    "        \"alpha.exposures\" : portfolio_alpha_exposure,\n",
    "        \"total.cost\" : total_transaction_costs}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build tradelist\n",
    "\n",
    "The trade list is the most recent optimal asset holdings minus the previous day's optimal holdings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_tradelist(prev_holdings, opt_result):\n",
    "    tmp = prev_holdings.merge(opt_result['opt.portfolio'], how='outer', on = 'Barrid')\n",
    "    tmp['h.opt.previous'] = np.nan_to_num(tmp['h.opt.previous'])\n",
    "    tmp['h.opt'] = np.nan_to_num(tmp['h.opt'])\n",
    "    return tmp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Save optimal holdings as previous optimal holdings.\n",
    "\n",
    "As we walk through each day, we'll re-use the column for previous holdings by storing the \"current\" optimal holdings as the \"previous\" optimal holdings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "def convert_to_previous(result): \n",
    "    prev = result['opt.portfolio']\n",
    "    prev = prev.rename(index=str, columns={\"h.opt\": \"h.opt.previous\"}, copy=True, inplace=False)\n",
    "    return prev"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the backtest\n",
    "\n",
    "Walk through each day, calculating the optimal portfolio holdings and trade list.  This may take some time, but should finish sooner if you've chosen all the optimizations you learned in the lessons."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Optimizing Portfolio: 100%|██████████| 252/252 [22:33<00:00,  5.37s/day]\n"
     ]
    }
   ],
   "source": [
    "trades = {}\n",
    "port = {}\n",
    "\n",
    "for dt in tqdm(my_dates, desc='Optimizing Portfolio', unit='day'):\n",
    "    date = dt.strftime('%Y%m%d')\n",
    "\n",
    "    result = form_optimal_portfolio(frames[date], previous_holdings, risk_aversion)\n",
    "    trades[date] = build_tradelist(previous_holdings, result)\n",
    "    port[date] = result\n",
    "    previous_holdings = convert_to_previous(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Profit-and-Loss (PnL) attribution (TODO)\n",
    "\n",
    "Profit and Loss is the aggregate realized daily returns of the assets, weighted by the optimal portfolio holdings chosen, and summed up to get the portfolio's profit and loss.\n",
    "\n",
    "The PnL attributed to the alpha factors equals the factor returns times factor exposures for the alpha factors.  \n",
    "\n",
    "$$\n",
    "\\mbox{PnL}_{alpha}= f \\times b_{alpha}\n",
    "$$\n",
    "\n",
    "Similarly, the PnL attributed to the risk factors equals the factor returns times factor exposures of the risk factors.\n",
    "\n",
    "$$\n",
    "\\mbox{PnL}_{risk} = f \\times b_{risk}\n",
    "$$\n",
    "\n",
    "In the code below, in the function `build_pnl_attribution` calculate the PnL attributed to the alpha factors, the PnL attributed to the risk factors, and attribution to cost. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "## assumes v, w are pandas Series \n",
    "def partial_dot_product(v, w):\n",
    "    common = v.index.intersection(w.index)\n",
    "    return np.sum(v[common] * w[common])\n",
    "\n",
    "def build_pnl_attribution(): \n",
    "\n",
    "    df = pd.DataFrame(index = my_dates)\n",
    "    \n",
    "    for dt in my_dates:\n",
    "        date = dt.strftime('%Y%m%d')\n",
    "\n",
    "        p = port[date]\n",
    "        fr = facret[date]\n",
    "\n",
    "        mf = p['opt.portfolio'].merge(frames[date], how = 'left', on = \"Barrid\")\n",
    "        \n",
    "        mf['DlyReturn'] = wins(mf['DlyReturn'], -0.5, 0.5)\n",
    "        df.at[dt,\"daily.pnl\"] = np.sum(mf['h.opt'] * mf['DlyReturn'])\n",
    "        \n",
    "        # TODO: Implement\n",
    "    \n",
    "        df.at[dt,\"attribution.alpha.pnl\"] = partial_dot_product(fr, p['alpha.exposures'])\n",
    "        df.at[dt,\"attribution.risk.pnl\"] = partial_dot_product(fr, p['risk.exposures'])\n",
    "        df.at[dt,\"attribution.cost\"] = p['total.cost']\n",
    "        \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f80306b53c8>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "attr = build_pnl_attribution()\n",
    "\n",
    "for column in attr.columns:\n",
    "        plt.plot(attr[column].cumsum(), label=column)\n",
    "plt.legend(loc='upper left')\n",
    "plt.xlabel('Date')\n",
    "plt.ylabel('PnL Attribution')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build portfolio characteristics (TODO)\n",
    "Calculate the sum of long positions, short positions, net positions, gross market value, and amount of dollars traded.\n",
    "\n",
    "In the code below, in the function `build_portfolio_characteristics` calculate the sum of long positions, short positions, net positions, gross market value, and amount of dollars traded.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_portfolio_characteristics(): \n",
    "    df = pd.DataFrame(index = my_dates)\n",
    "    \n",
    "    for dt in my_dates:\n",
    "        date = dt.strftime('%Y%m%d')\n",
    "  \n",
    "        p = port[date]\n",
    "        tradelist = trades[date]\n",
    "        h = p['opt.portfolio']['h.opt']\n",
    "        \n",
    "        # TODO: Implement\n",
    "        \n",
    "        df.at[dt,\"long\"] = np.sum(h[h > 0])\n",
    "        df.at[dt,\"short\"] = np.sum(h[h < 0])\n",
    "        df.at[dt,\"net\"] = np.sum(h)\n",
    "        df.at[dt,\"gmv\"] = np.sum(abs(h))\n",
    "        df.at[dt,\"traded\"] = np.sum(np.abs(tradelist[\"h.opt\"] - tradelist[\"h.opt.previous\"]))\n",
    "        \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f80302bb358>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pchar = build_portfolio_characteristics()\n",
    "\n",
    "for column in pchar.columns:\n",
    "        plt.plot(pchar[column], label=column)\n",
    "plt.legend(loc='upper left')\n",
    "plt.xlabel('Date')\n",
    "plt.ylabel('Portfolio')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Optional\n",
    "Choose additional metrics to evaluate your portfolio."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Submission\n",
    "Now that you're done with the project, it's time to submit it. Click the submit button in the bottom right. One of our reviewers will give you feedback on your project with a pass or not passed grade."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
